SESで受信したメールをLambdaで別の宛先に転送してみた
SESで受信したメールを、別の宛先へ転送してみたいと思います。ここでは、AWS WorkMailやMTAは利用せず、SES + Lambda Functionで実装してみたいと思います。
構成イメージ
SESでメールを受信し、受信をトリガーにLambda Functionを起動させ、SESの送信APIを利用して別の宛先に送信するといったシナリオです。
前提
- メールアドレスに使用するドメインのネームサーバがRoute53で管理されていること
- SESで有効な受信ルールセット(Active Rule Set)が存在しないこと
やってみた
メール保存バケット作成
受信メール保存用バケット(ここでは、test-ses-receiving-mail
)を作成し、SESにそのバケットに対する書き込み権限を与えます。バケット名、アカウントIDについては環境にあわせ変更してください。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowSESPuts", "Effect": "Allow", "Principal": { "Service": "ses.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::バケット名/*", "Condition": { "StringEquals": { "aws:Referer": "アカウントID" } } } ] }
Lambda Function作成
メールを転送するLambda Functionを作成します。 ここでは、受信したメールを読み込み、SESのAPIで送信処理のみ実装しています。
import os import boto3 import logging s3_client = boto3.client('s3') ses_client = boto3.client('ses') logger = logging.getLogger() logger.setLevel(logging.INFO) s3_bucket = os.environ['S3_BUCKET'] forward_to = os.environ['FORWARD_TO'] def send_mail(message): ses_client.send_raw_email( Source = forward_to, Destinations=[ forward_to ], RawMessage={ 'Data': message } ) def lambda_handler(event, context): logger.info(event) #メッセージID取得 message_id=event['Records'][0]['ses']['mail']['messageId'] #メッセージIDをキーにS3オブジェクト(メール)取得 response = s3_client.get_object( Bucket = s3_bucket, Key = message_id ) # Emlデータ取得 raw_message = response['Body'].read() # メール送信 send_mail(raw_message)
受信メールの保存用バケットと、転送先アドレスは環境変数に設定しています。
ドメイン検証
メールアドレスに使用するドメインの所有権を確認します。
SESコンソールより「Domains」-「Verify New Domain」をクリックします。
メールアドレスで利用するドメインを入力します。ここではses-receiving.nochan.work
を設定し「Verify This Domain」をクリックします。
ドメイン検証用のレコードセットが表示されます。ここではネームサーバにRoute 53を利用しているので「Use Route 53」をクリックします。
「Email Receiving Record」にチェックを付与し「Create Record Sets」をクリックします。なお、Route 53のドメインのMXレコードは上書きされますので、ドメイン名に間違いがないかご注意ください。
ホストゾーンに先程表示されたレコードが追加されます。ステータスが「verified」になったことを確認します。
受信ルール作成
受信したメールの処理条件などを定義します。
「Rule Sets」-「Crate a Rule Set」をクリックします。
任意のルール名を入力し「Crate a Rule Set」をクリックします。
画面を更新すると、作成した受信ルールが有効化されていると思いますので、有効化されていることを確認し「View Active Rule Set」をクリックします。
「Create Rule」をクリックします。
ここでは、ユーザ名は指定せずドメイン名(ses-receiving.nochan.work
)を入力し「Add Recipient」をクリックします。
ドメインの検証は済んでいますので「Next Step」をクリックします。
以下のアクションを指定し「Next Step」をクリックします。
- Action…S3
- S3 bucket…作成したバケット(ここでは、
test-ses-receiving-mail
) - Action…Lambda
- Lambda function…作成したLambda Function(ここでは、
TransferMail
)
任意のルール名を入力し「Next Step」をクリックします。
設定内容を確認し「Create Rule」をクリックします。
作成したルールのステータスが「Enabled」になっていることを確認します。
SES送信設定(メールアドレス登録)
メールを送信する前に「From」アドレスの所有確認が必要になります。アカウントがサンドボックスにある場合は「To」アドレスも確認する必要がありますので、誰にでもメールを送信する際はサンドボックスの解除が必要になります。
今回はサンドボックスを解除せず実施しますので、「From」と「To」アドレスの2つの所有を確認します。
「Email Addresses」-「Verify a New Email Address」をクリックします。
利用するメールアドレスを入力し「Verify This Email Address」をクリックします。
指定したメールアドレスに検証要求メールが届きますので、リンクをクリックして承認します。
同様の手順で「From」、「To」2つのアドレスの所有を確認しました。
動作確認
受信用に設定したドメインに対してメールを送信して、指定した宛先にメールが送信されるか確認してみたいと思います。
SESでメール受信ができると、保存用バケットにメールが保存されます。
受信ルールで設定したLambda Functionが動作し、指定のアドレスにメールが転送されました。
さいごに
S3のPUTトリガーでLambda Functionを起動させても同じようなことができると思いましたが、今回はトリガーをSESに寄せてみました。誰かのお役に立てれば幸いです。